package com.zz.inventory.controller;

import java.util.*;

import com.alibaba.excel.EasyExcel;
import com.alibaba.nacos.api.model.v2.Result;
import com.ruoyi.common.core.utils.StringUtils;
import com.zz.inventory.config.SchoolRedisService;
import com.zz.inventory.domain.Labs;
import com.zz.inventory.feign.StudentFeignClient;
import com.zz.inventory.feign.TeacherExamFeignClient;
import com.zz.inventory.mapper.StudentsMapper;
import com.zz.inventory.service.ILabsService;
import jakarta.servlet.http.HttpServletResponse;
import com.zz.inventory.domain.Students;
import lombok.extern.slf4j.Slf4j;
import org.example.dto.StudentInfoDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.zz.inventory.service.IStudentsService;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 学生信息Controller
 * 
 * @author ruoyi
 * @date 2025-07-03
 */
@RestController
@Slf4j
@RequestMapping("/students")
public class StudentsController extends BaseController {
    @Autowired
    private IStudentsService studentsService;
    @Autowired
    private SchoolRedisService schoolRedisService;
    @Autowired
    private StudentsMapper studentsMapper;
    @Autowired
    TeacherExamFeignClient teacherExamFeignClient;
    @Autowired
    StudentFeignClient studentFeignClient;
    @Autowired
    ILabsService iLabsService;


    /**
     * 查询机房列表，传给前端封装，考试信息
     * @return
     */
    @GetMapping("/listjifang")
    public TableDataInfo listjifang() {
        Labs labs = new Labs();
        List<Labs> jifang = iLabsService.selectLabsList(labs);
        return getDataTable(jifang);
    }


    /**
     * 查询学生信息列表
     */
    @RequiresPermissions("schoolmanage:students:list")
    @GetMapping("/list")
    public TableDataInfo list(Students students) {
        startPage();
        List<Students> list = studentsService.selectStudentsList(students);
        return getDataTable(list);
    }

    /**
     * 导出学生信息列表
     */
    @RequiresPermissions("schoolmanage:students:export")
    @Log(title = "学生信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Students students) {
        List<Students> list = studentsService.selectStudentsList(students);
        ExcelUtil<Students> util = new ExcelUtil<Students>(Students.class);
        util.exportExcel(response, list, "学生信息数据");
    }

    /**
     * 获取学生信息详细信息
     */
    @RequiresPermissions("schoolmanage:students:query")
    @GetMapping(value = "/{studentId}")
    public AjaxResult getInfo(@PathVariable("studentId") Long studentId) {
        // 先从缓存获取
        Students cachedStudent = schoolRedisService.getCachedStudent(studentId);
        if (cachedStudent != null) {
            return success(cachedStudent);
        }

        // 缓存没有则从数据库获取
        Students student = studentsService.selectStudentsByStudentId(studentId);
        if (student != null) {
            schoolRedisService.cacheStudent(student);
        }
        return success(student);
    }

    /**
     * 获取学生信息详细信息
     */
    @GetMapping("/add")
    public AjaxResult student(Students students) {
        return success(studentsService.selectStudentsList(students));
    }


    /**
     * 新增学生信息
     */
    @RequiresPermissions("schoolmanage:students:add")
    @Log(title = "学生信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Students students) {
        log.info("新增学生-收到请求: {}", students); // 打印请求数据
        int result = studentsService.insertStudents(students);
        log.info("新增学生-数据库操作结果:{}, 生成ID:{}", result, students.getStudentId());

        if (result > 0){
            schoolRedisService.cacheStudent(students);
        }
        return toAjax(result);
    }

    /**
     * 修改学生信息
     */
    @RequiresPermissions("schoolmanage:students:edit")
    @Log(title = "学生信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Students students) {
        int result = studentsService.updateStudents(students);
        if (result > 0) {
            // 更新成功后更新缓存
            schoolRedisService.cacheStudent(students);
        }
        return toAjax(result);
    }



    /**
     * 导入学生信息
     */
    @PostMapping("/importData")
    public AjaxResult importData(@RequestParam("file") MultipartFile file) {
        // 初始化错误集合
        List<String> errors = new ArrayList<>();

        try {
            // 1. 读取Excel数据
            List<Students> list = EasyExcel.read(file.getInputStream())
                    .head(Students.class)
                    .sheet()
                    .doReadSync();

            // 2. 数据验证
            for (int i = 0; i < list.size(); i++) {
                Students s = list.get(i);

                // 必填字段验证
                if (s.getClassId() == null) {
                    errors.add("第" + (i+2) + "行: 班级ID不能为空");
                }
                if (StringUtils.isBlank(s.getStudentCode())) {
                    errors.add("第" + (i+2) + "行: 学号不能为空");
                }
                if (StringUtils.isBlank(s.getFullName())) {
                    errors.add("第" + (i+2) + "行: 学生姓名不能为空");
                }

                // 设置默认值
                if (s.getCreateTime() == null) {
                    s.setCreateTime(new Date());
                }
            }

            // 3. 处理验证结果
            if (!errors.isEmpty()) {
                return error("导入失败:\n" + String.join("\n", errors));
            }

            // 4. 调用服务层
            return success(studentsService.importStudents(list));
        } catch (Exception e) {
            logger.error("导入异常", e);
            return error("系统错误: " + e.getMessage());
        }
    }




    /**
     * 删除学生信息
     */

    @RequiresPermissions("schoolmanage:students:remove")
    @Log(title = "学生信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/batch/{studentIds}")
    public AjaxResult batchRemove(@PathVariable Long[] studentIds) {
        List<Long> successIds = new ArrayList<>();
        List<Long> failedIds = new ArrayList<>();
        Map<Long, String> failedReasons = new HashMap<>();

        for (Long studentId : studentIds) {
            try {
                // 检查关联
                AjaxResult checkResult = checkAssociations(studentId);
                if (Boolean.TRUE.equals(checkResult.get("hasRecords"))) {
                    failedIds.add(studentId);
                    failedReasons.put(studentId, (String) checkResult.get("msg"));
                    continue;
                }

                // 执行删除
                int rows = studentsService.deleteStudentsByStudentId(studentId);
                if (rows > 0) {
                    successIds.add(studentId);
                } else {
                    failedIds.add(studentId);
                    failedReasons.put(studentId, "删除失败");
                }
            } catch (Exception e) {
                failedIds.add(studentId);
                failedReasons.put(studentId, e.getMessage());
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("success", successIds);
        result.put("failed", failedReasons);

        if (failedIds.isEmpty()) {
            return AjaxResult.success("批量删除成功", result);
        } else {
            return successIds.isEmpty()
                    ? AjaxResult.error("批量删除全部失败", result)
                    : AjaxResult.success("部分删除成功", result);
        }

    }

    //远程调用,,,,,1调用考试服务检查是否有记录
    @GetMapping("/check-associations/{studentId}")      //1
    public AjaxResult checkAssociations(@PathVariable Long studentId) {
        Map<String, Object> result = new HashMap<>();
        try {
            // 1. 调用考试记录服务
            AjaxResult examResult = teacherExamFeignClient.getStudentExamRecords(studentId);

            // 2. 规范化结果处理
            if (!examResult.isSuccess()) {
                return examResult; // 直接返回错误信息
            }

            Map<String, Object> data = (Map<String, Object>) examResult.get(AjaxResult.DATA_TAG);
            boolean hasRecords = Boolean.TRUE.equals(data.get("hasAssociatedRecords"));
            int count = hasRecords ? (int) data.get("count") : 0; // 确保获取记录数

            // 3. 统一返回字段名
            result.put("hasRecords", hasRecords);
            result.put("count", count); // 必须返回记录数
            result.put("msg", hasRecords ?
                    "存在 " + count + " 条关联记录" : "无关联记录");

            return AjaxResult.success(result);
        } catch (Exception e) {
            logger.error("检查关联数据异常", e);
            return AjaxResult.error("检查异常: " + e.getMessage());
        }
    }

    @DeleteMapping("/{studentId}")
    public AjaxResult deleteStudent(@PathVariable Long studentId) {
        int result = studentsService.deleteStudentsByStudentId(studentId);
        if (result > 0) {
            // 删除成功后清除缓存
            schoolRedisService.removeCachedStudent(studentId);
        }
        return toAjax(result);
    }

    @GetMapping("/studentsWithClassName")
    public Result<List<Students>> getStudentList() {
        List<Students> students = studentsMapper.selectStudentWithClassName();
        return Result.success(students);
    }

    @PostMapping("/studentExam")
    public AjaxResult info(@RequestBody Map<String, Object> requestData) {
        try {
            // 1. 数据校验
            if (requestData.get("examNumber") == null || requestData.get("lasName") == null) {
                return AjaxResult.error("考试编号和机房名称不能为空");
            }
            String examNumber = requestData.get("examNumber").toString(); // 转为String
            String lasName = requestData.get("lasName").toString();

            if (examNumber.trim().isEmpty() || lasName.trim().isEmpty()) {
                return AjaxResult.error("参数值不能为空字符串");
            }
            StudentInfoDTO studentInfoDTO = StudentInfoDTO.builder()
                    .examNumber(examNumber)
                    .lasName(lasName)
                    .build();

            //3,远程调用，存储学生考试信息
            StudentInfoDTO studentInfo = studentFeignClient.getStudentInfo(studentInfoDTO);
            return AjaxResult.success("考试配置保存成功");
        } catch (Exception e) {
            return AjaxResult.error("保存失败" + e.getMessage());
        }
    }


}
